package org.com.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.com.pojo.ChatMessage;
import org.com.service.ChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;

@Component
public class ChatWebSocketHandler extends TextWebSocketHandler {
    
    private static final Map<Integer, WebSocketSession> userSessions = new ConcurrentHashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private ChatService chatService;
    
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        // 从session中获取用户ID
        Integer userId = getUserId(session);
        if (userId != null) {
            userSessions.put(userId, session);
            System.out.println("WebSocket连接已建立 - 用户ID: " + userId);
            System.out.println("当前在线用户数: " + userSessions.size());
            System.out.println("在线用户列表: " + userSessions.keySet());
        } else {
            System.out.println("WebSocket连接建立失败 - 未能获取用户ID");
        }
    }
    
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 解析消息
        Map<String, Object> messageMap = objectMapper.readValue(message.getPayload(), Map.class);
        String messageType = (String) messageMap.get("type");
        
        System.out.println("收到消息类型: " + messageType);
        
        switch (messageType) {
            case "init":
                handleInitMessage(session, messageMap);
                break;
            case "heartbeat":
                handleHeartbeat(session, messageMap);
                break;
            case "chat":
                handleChatMessage(session, messageMap);
                break;
            default:
                System.out.println("未知消息类型: " + messageType);
                break;
        }
    }
    
    private void handleInitMessage(WebSocketSession session, Map<String, Object> messageMap) throws Exception {
        Integer userId = getUserId(session);
        System.out.println("处理初始化消息 - 用户ID: " + userId);
        
        // 发送初始化成功响应
        Map<String, Object> response = new HashMap<>();
        response.put("type", "init");
        response.put("success", true);
        response.put("message", "连接成功");
        response.put("userId", userId);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }
    
    private void handleHeartbeat(WebSocketSession session, Map<String, Object> messageMap) throws Exception {
        Integer userId = getUserId(session);
        System.out.println("收到心跳消息 - 用户ID: " + userId);
        
        // 发送心跳响应
        Map<String, Object> response = new HashMap<>();
        response.put("type", "heartbeat");
        response.put("timestamp", System.currentTimeMillis());
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }
    
    private void handleChatMessage(WebSocketSession session, Map<String, Object> messageMap) throws Exception {
        try {
            System.out.println("处理聊天消息: " + messageMap);
            
            // 将Map转换为ChatMessage对象，处理类型转换
            ChatMessage chatMessage = new ChatMessage();
            
            // 处理 fromUserId
            Object fromUserIdObj = messageMap.get("fromUserId");
            if (fromUserIdObj instanceof Integer) {
                chatMessage.setFromUserId((Integer) fromUserIdObj);
            } else if (fromUserIdObj instanceof String) {
                chatMessage.setFromUserId(Integer.parseInt((String) fromUserIdObj));
            }
            
            // 处理 toUserId
            Object toUserIdObj = messageMap.get("toUserId");
            if (toUserIdObj instanceof Integer) {
                chatMessage.setToUserId((Integer) toUserIdObj);
            } else if (toUserIdObj instanceof String) {
                chatMessage.setToUserId(Integer.parseInt((String) toUserIdObj));
            }
            
            chatMessage.setContent((String) messageMap.get("content"));
            
            System.out.println("转换后的消息对象: " + chatMessage);
            
            // 保存消息到数据库
            boolean saved = chatService.sendMessage(chatMessage);
            if (!saved) {
                System.out.println("消息保存失败");
                sendErrorMessage(session, "消息保存失败");
                return;
            }
            
            // 如果接收者在线，直接发送消息
            WebSocketSession recipientSession = userSessions.get(chatMessage.getToUserId());
            if (recipientSession != null && recipientSession.isOpen()) {
                recipientSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(messageMap)));
                System.out.println("消息已转发给接收者: " + chatMessage.getToUserId());
            } else {
                System.out.println("接收者不在线或会话已关闭: " + chatMessage.getToUserId());
            }
        } catch (Exception e) {
            System.err.println("处理聊天消息时发生错误: " + e.getMessage());
            e.printStackTrace();
            sendErrorMessage(session, "消息处理失败: " + e.getMessage());
        }
    }
    
    private void sendErrorMessage(WebSocketSession session, String errorMessage) throws Exception {
        Map<String, Object> errorResponse = new HashMap<>();
        errorResponse.put("type", "error");
        errorResponse.put("message", errorMessage);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(errorResponse)));
    }
    
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        Integer userId = getUserId(session);
        if (userId != null) {
            userSessions.remove(userId);
            System.out.println("WebSocket连接已关闭 - 用户ID: " + userId);
            System.out.println("当前在线用户数: " + userSessions.size());
            System.out.println("在线用户列表: " + userSessions.keySet());
        }
    }
    
    private Integer getUserId(WebSocketSession session) {
        Map<String, Object> attributes = session.getAttributes();
        Integer userId = (Integer) attributes.get("userId");
        System.out.println("获取用户ID: " + userId + ", 会话属性: " + attributes);
        return userId;
    }
    
    // 获取在线用户列表
    public Set<Integer> getOnlineUsers() {
        System.out.println("获取在线用户列表 - 当前在线用户数: " + userSessions.size());
        System.out.println("在线用户列表: " + userSessions.keySet());
        return new HashSet<>(userSessions.keySet());
    }

    // 检查用户是否在线
    public boolean isUserOnline(Integer userId) {
        boolean isOnline = userSessions.containsKey(userId);
        System.out.println("检查用户在线状态 - 用户ID: " + userId + ", 是否在线: " + isOnline);
        return isOnline;
    }
} 